# -*- coding: utf-8 -*-
"""
Created on Wed Aug  9 10:38:49 2023

@author: 李小斌
"""


import os
import math
import numpy as np
from sklearn.model_selection import KFold
#from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.ensemble import BaggingRegressor
from sklearn.tree import ExtraTreeRegressor
from sklearn import neighbors
from sklearn import svm
from sklearn import tree
from sklearn import ensemble
from sklearn.metrics import mean_squared_error
import csv
#from gplearn import genetic
#from gplearn.genetic import SymbolicRegressor
#from datetime import datetime

dimension=400
    
def ontime(modelname,nfolds):
    csv_reader=csv.reader(open('all'+str(dimension)+'.csv'))
    
    L1=[]
    y=[]                        #期末成绩,final
    x1=[]                        #平时所有数据
    x2=[]
    #xtest=[]                    #平时测验
    #xhomework=[]                #平时2次作业
    #xexperiment=[]              #平时的16次实验
    #xevaluation=[]              #教学评价
    
    n=0
    for row in csv_reader:
        if n==0:
            n=n+1
            continue
        n=n+1
        y.append(row[1])                    #final
        x1.append(row[2:22])
        x2.append(row[22:22+3*dimension])              #2次平时

    
    #将所有数据转化为float类型数据
    ya=np.array(y,dtype=float)
    ya=ya/100
    x1a=np.array(x1,dtype=float)
    x1a=x1a/100
    x2a=np.array(x2,dtype=float)
    xa=np.hstack((x1a,x2a))                          

    
    #nfolds=5
    kf = KFold(n_splits=nfolds,shuffle=False)  # 初始化KFold
    if modelname=='LR':
        model = LinearRegression()
    elif modelname=='Ridge':
        model = Ridge(alpha=.5)
    elif modelname=='Lasso':
        model=Lasso(alpha=.5)
    elif modelname=='SVR':
        model=svm.SVR()
    elif modelname=='DT':
        model=tree.DecisionTreeRegressor()
    elif modelname=='KNN':
        model=neighbors.KNeighborsRegressor()
    elif modelname=='RandomForest':
        model=ensemble.RandomForestRegressor(n_estimators=20)
    elif modelname=='Adaboost':
        model=ensemble.AdaBoostRegressor(n_estimators=20)
    elif modelname=='GBRT':
        model=ensemble.GradientBoostingRegressor(n_estimators=20)
    elif modelname=='Bagging':
        model=BaggingRegressor()
    elif modelname=='ExtraTree':
        model=ExtraTreeRegressor()
        
    for train_index , test_index in kf.split(ya):  # 调用split方法切分数据
    
        #model1=model
        
        model.fit(xa[train_index],ya[train_index])
        yp=model.predict(xa[test_index])
        rmse=math.sqrt(mean_squared_error(ya[test_index],yp))
        L1.append(rmse)
        
  
    return [L1]

def evaluate(modelname,ntimes,nfolds):
    file=open(modelname+'.csv','w',newline='')       
    f_csv=csv.writer(file)
    header=['rmse']
    f_csv.writerow(header)
    times=0
    while times<ntimes:
        L=ontime(modelname,nfolds)
        Lw=[]           #用于获取L1-L8中相同位置的rmse，构造成一个list存入csv    
        for pos in range(0,nfolds):
            for Litem in L:
                Lw.append(Litem[pos])
            f_csv.writerow(Lw)
            Lw=[]
        times+=1
    file.close()

def getRmse(modelname):
    filepath=modelname+'.csv'
    file=open(filepath)
    csv_reader=csv.reader(file)    
    x=[]
    n=0
    for row in csv_reader:
        if n==0:
            n=n+1
            continue
        n=n+1
        x.append(row[0])                    
    #将所有数据转化为float类型数据
    file.close()
    os.remove(filepath)
    xa=np.array(x,dtype=float)
    return np.mean(xa)
    
def main():
    #模型名称，LR,Ridge,Lasso,SVR,DT,KNN,RandomForest,Adaboost,GBRT,Bagging,ExtraTree
    ntimes=20#运行总次数
    nfolds=5#fold的次数
    modelnames=['LR','Ridge','Lasso','SVR','DT','KNN','RandomForest',
                'Adaboost','GBRT','Bagging','ExtraTree']
    file=open('feature_fusion'+str(dimension)+'.csv','w',newline='')       
    f_csv=csv.writer(file)
    for modelname in modelnames:
        evaluate(modelname,ntimes,nfolds)
        v=getRmse(modelname)
        print(modelname,":",v)
        f_csv.writerow([modelname,v])
    file.close()
if __name__=="__main__":
    main()